//=========================================================================
// Copyright (C) 2021 The C++ Component Model(COMO) Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//=========================================================================

#include "libuuid-1.0.3/uuid.h"
#include "cityhash/cityhash.h"
#include "option.h"
#include <cstring>
#include <iostream>
using namespace std;

typedef struct tagUUID {
    unsigned int mData1;
    unsigned short mData2;
    unsigned short mData3;
    unsigned short mData4;
    unsigned char mData5[6];
} UUID;

int main(int argc, char **argv)
{
    Options options(argc, argv);

    if (options.DoShowUsage()) {
        options.ShowUsage();
        return 0;
    }

    if (options.HasErrors()) {
        options.ShowErrors();
        return 0;
    }

    if (options.DoShowUriString()) {
        uuid_t uuid;
        char str[36];
        uuid_generate(uuid);
        if (options.mCppFormat) {
            UUID *uuid_c = (UUID *)&uuid;
            printf("{0x%08x,0x%04x,0x%04x,0x%04x,"
                    "{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}}\n",
                    uuid_c->mData1, uuid_c->mData2, uuid_c->mData3, uuid_c->mData4,
                    uuid_c->mData5[0], uuid_c->mData5[1], uuid_c->mData5[2],
                    uuid_c->mData5[3], uuid_c->mData5[4], uuid_c->mData5[5]);
        }
        else {
            uuid_unparse(uuid, str);
            printf("%s\n", str);
        }
        return 0;
    }

    if (options.DoGenerateHash()) {
        uint128 hash128 = CityHash128(options.getHashString().c_str(),
                                      options.getHashString().length());
        UUID *uuid_c = (UUID *)&hash128;
        if (options.mCppFormat) {
            printf("{0x%08x,0x%04x,0x%04x,0x%04x,"
                    "{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}}\n",
                    uuid_c->mData1, uuid_c->mData2, uuid_c->mData3, uuid_c->mData4,
                    uuid_c->mData5[0], uuid_c->mData5[1], uuid_c->mData5[2],
                    uuid_c->mData5[3], uuid_c->mData5[4], uuid_c->mData5[5]);
        }
        else {
            printf("%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\n",
                    uuid_c->mData1, uuid_c->mData2, uuid_c->mData3, uuid_c->mData4,
                    uuid_c->mData5[0], uuid_c->mData5[1], uuid_c->mData5[2],
                    uuid_c->mData5[3], uuid_c->mData5[4], uuid_c->mData5[5]);
        }
    }

    return 0;
}
